package com.shiyipicture.shiyipicturebackend.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shiyipicture.shiyipicturebackend.api.aliyun.AliYunAiApi;
import com.shiyipicture.shiyipicturebackend.api.aliyun.model.CreateOutPaintingTaskRequest;
import com.shiyipicture.shiyipicturebackend.api.aliyun.model.CreateOutPaintingTaskRequest.Input;
import com.shiyipicture.shiyipicturebackend.api.aliyun.model.CreateOutPaintingTaskRequest.Parameters;
import com.shiyipicture.shiyipicturebackend.api.aliyun.model.CreateOutPaintingTaskResponse;
import com.shiyipicture.shiyipicturebackend.enums.PictureReviewStatusEnum;
import com.shiyipicture.shiyipicturebackend.enums.UserRoleEnum;
import com.shiyipicture.shiyipicturebackend.exception.BusinessException;
import com.shiyipicture.shiyipicturebackend.exception.ErrorCode;
import com.shiyipicture.shiyipicturebackend.exception.ThrowUtils;
import com.shiyipicture.shiyipicturebackend.manager.CosManager;
import com.shiyipicture.shiyipicturebackend.manager.FileManager;
import com.shiyipicture.shiyipicturebackend.manager.upload.FileManagerTemplate;
import com.shiyipicture.shiyipicturebackend.manager.upload.FilePictureUpload;
import com.shiyipicture.shiyipicturebackend.manager.upload.UrlPictureUpload;
import com.shiyipicture.shiyipicturebackend.mapper.PictureMapper;
import com.shiyipicture.shiyipicturebackend.model.dto.file.UploadPictureResult;
import com.shiyipicture.shiyipicturebackend.model.dto.picture.*;
import com.shiyipicture.shiyipicturebackend.model.entity.Picture;
import com.shiyipicture.shiyipicturebackend.model.entity.Space;
import com.shiyipicture.shiyipicturebackend.model.entity.User;
import com.shiyipicture.shiyipicturebackend.model.vo.PictureVO;
import com.shiyipicture.shiyipicturebackend.model.vo.UserVO;
import com.shiyipicture.shiyipicturebackend.service.PictureService;
import com.shiyipicture.shiyipicturebackend.service.SpaceService;
import com.shiyipicture.shiyipicturebackend.service.UserService;
import com.shiyipicture.shiyipicturebackend.utils.ColorSimilarUtils;

import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;


/**
 * @author Administrator
 * @description 针对表【picture(图片)】的数据库操作Service实现
 * @createDate 2025-01-06 15:15:24
 */
@Service
@Slf4j
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
  implements PictureService {

  @Resource
  private FileManager fileManager;

  @Resource
  private UserService userService;

  @Resource
  private FilePictureUpload filePictureUpload;

  @Resource
  private UrlPictureUpload urlPictureUpload;

  @Resource
  private SpaceService spaceService;

  @Resource
  private CosManager cosManager;

  @Resource
  private TransactionTemplate transactionTemplate;

  @Resource
  private ThreadPoolExecutor threadPoolExecutor;

  @Resource
  private AliYunAiApi aliYunAiApi;


  @Override
  public PictureVO uploadPicture(Object inputSource, PictureUploadRequest pictureUploadRequest, User loginUser) {
    ThrowUtils.throwIf(loginUser == null, ErrorCode.NO_AUTH_ERROR, "无权限");
    Long spaceId = pictureUploadRequest.getSpaceId();
    if (spaceId != null) {
      Space space = spaceService.getById(spaceId);
      ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在 ");
//      if (!space.getUserId().equals(loginUser.getId())) {
//        throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "没有空间权限");
//      }
      if (space.getTotalSize() >= space.getMaxCount()) {
        throw new BusinessException(ErrorCode.OPERATION_ERROR, "空间条数不足");
      }
      if (space.getTotalSize() >= space.getMaxSize()) {
        throw new BusinessException(ErrorCode.OPERATION_ERROR, "空间大小不足");
      }
    }

    //用于判断是否是更新图片
    Long pictureId = null;
    if (pictureUploadRequest != null) {
      pictureId = pictureUploadRequest.getId();
    }

    //如果是更新图片需要判断图片是否存在
    if (pictureId != null) {
      Picture picture = this.getById(pictureId);
      ThrowUtils.throwIf(picture == null, ErrorCode.OPERATION_ERROR, "待更新图片不存在");
    }
    //上传图片 根据用户Id划分目录
    String uploadPathPrefix;

    if (spaceId != null) {
      uploadPathPrefix = String.format("public/%s", spaceId);
    } else {
      uploadPathPrefix = String.format("public/%s", loginUser.getId());
    }
    //模板方法优化 实现文件上传图片和 url上传图片
    FileManagerTemplate fileManagerTemplate = filePictureUpload;
    if (inputSource instanceof String) {
      fileManagerTemplate = urlPictureUpload;
    }
    UploadPictureResult uploadPictureResult = fileManagerTemplate.uploadPicture(inputSource, uploadPathPrefix);
    //构建要入库的图片信息
    Picture picture = new Picture();
    String picName = uploadPictureResult.getPicName();
    if (pictureUploadRequest != null && StrUtil.isNotBlank(pictureUploadRequest.getPickName())) {
      picName = pictureUploadRequest.getPickName();
    }
    picture.setUrl(uploadPictureResult.getUrl());
    picture.setThumbnailUrl(uploadPictureResult.getThumbnailUrl());
    picture.setName(picName);
    picture.setPicSize(uploadPictureResult.getPicSize());
    picture.setPicWidth(uploadPictureResult.getPicWidth());
    picture.setPicHeight(uploadPictureResult.getPicHeight());
    picture.setPicScale(uploadPictureResult.getPicScale());
    picture.setPicFormat(uploadPictureResult.getPicFormat());
    picture.setUserId(loginUser.getId());
    picture.setSpaceId(spaceId);
    picture.setPicColor(uploadPictureResult.getPicColor());
    //如果pictureId不为空则表示更新，否则是新增
    if (pictureId != null) {
      picture.setEditTime(new Date());
      picture.setId(pictureId);
    }
    this.fillReviewParams(picture, loginUser);

    Long finalSpaceId = spaceId;
    transactionTemplate.execute(status -> {
      boolean result = this.saveOrUpdate(picture);
      ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "图片上传失败");
      if (finalSpaceId != null) {
        boolean update = spaceService.lambdaUpdate().eq(Space::getId, finalSpaceId)
          .setSql("totalSize = totalSize + ", picture.getPicSize())
          .setSql("totalCount = totalCount + 1")
          .update();
        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "额度更新失败");
      }
      return picture;
    });
    return PictureVO.objToVo(picture);
  }

  @Override
  public QueryWrapper<Picture> getQueryWrapper(PictureQueryRequest pictureQueryRequest) {

    if (pictureQueryRequest == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
    }
    Long id = pictureQueryRequest.getId();
    String name = pictureQueryRequest.getName();
    String introduction = pictureQueryRequest.getIntroduction();
    String category = pictureQueryRequest.getCategory();
    List<String> tags = pictureQueryRequest.getTags();
    Long picSize = pictureQueryRequest.getPicSize();
    Integer picWidth = pictureQueryRequest.getPicWidth();
    Integer picHeight = pictureQueryRequest.getPicHeight();
    Double picScale = pictureQueryRequest.getPicScale();
    String picFormat = pictureQueryRequest.getPicFormat();
    String searchText = pictureQueryRequest.getSearchText();
    Long userId = pictureQueryRequest.getUserId();
    Integer reviewStatus = pictureQueryRequest.getReviewStatus();
    String reviewMessage = pictureQueryRequest.getReviewMessage();
    Long reviewerId = pictureQueryRequest.getReviewerId();
    Long spaceId = pictureQueryRequest.getSpaceId();
    Boolean nullSpaceId = pictureQueryRequest.getNullSpaceId();
    Date startEditTime = pictureQueryRequest.getStartEditTime();
    Date endEditTime = pictureQueryRequest.getEndEditTime();
    QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();

    if (StrUtil.isNotBlank(searchText)) {
      queryWrapper.and(qw -> qw.like("name", searchText)
        .or()
        .like("introduction", searchText)
      );
    }

    queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
    queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
    queryWrapper.like(StrUtil.isNotBlank(name), "name", name);
    queryWrapper.like(StrUtil.isNotBlank(introduction), "introduction", introduction);
    queryWrapper.like(StrUtil.isNotBlank(picFormat), "picFormat", picFormat);
    queryWrapper.like(StrUtil.isNotBlank(reviewMessage), "reviewMessage", reviewMessage);
    queryWrapper.eq(StrUtil.isNotBlank(category), "category", category);
    queryWrapper.eq(ObjUtil.isNotEmpty(picWidth), "picWidth", picWidth);
    queryWrapper.eq(ObjUtil.isNotEmpty(picHeight), "picHeight", picHeight);
    queryWrapper.eq(ObjUtil.isNotEmpty(picSize), "picSize", picSize);
    queryWrapper.eq(ObjUtil.isNotEmpty(picScale), "picScale", picScale);
    queryWrapper.eq(ObjUtil.isNotEmpty(reviewStatus), "reviewStatus", reviewStatus);
    queryWrapper.eq(ObjUtil.isNotEmpty(reviewerId), "reviewerId", reviewerId);
    queryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "spaceId", spaceId);
//    queryWrapper.isNull(nullSpaceId, "spaceId");
    queryWrapper.ge(ObjUtil.isNotEmpty(startEditTime), "editTime", startEditTime);
    queryWrapper.lt(ObjUtil.isNotEmpty(endEditTime), "editTime", endEditTime);

    // JSON 数组查询
    if (CollUtil.isNotEmpty(tags)) {
      for (String tag : tags) {
        queryWrapper.like("tags", "\"" + tag + "\"");
      }
    }
    return queryWrapper;
  }

  @Override
  public PictureVO getPictureVO(Picture picture, HttpServletRequest request) {
    // 对象转封装类
    PictureVO pictureVO = PictureVO.objToVo(picture);
    // 关联查询用户信息
    Long userId = picture.getUserId();
    if (userId != null) {
      User user = userService.getById(userId);
      UserVO userVo = userService.getUserVo(user);
      pictureVO.setUser(userVo);
    }
    return pictureVO;
  }

  /**
   * 分页获取图片封装
   */
  @Override
  public Page<PictureVO> getPictureVOPage(Page<Picture> picturePage, HttpServletRequest request) {
    List<Picture> pictureList = picturePage.getRecords();
    Page<PictureVO> pictureVOPage = new Page<>(picturePage.getCurrent(), picturePage.getSize(), picturePage.getTotal());
    if (CollUtil.isEmpty(pictureList)) {
      return pictureVOPage;
    }
    // 对象列表 => 封装对象列表
    List<PictureVO> pictureVOList = pictureList.stream().map(PictureVO::objToVo).collect(Collectors.toList());
    // 1. 关联查询用户信息
    Set<Long> userIdSet = pictureList.stream().map(Picture::getUserId).collect(Collectors.toSet());
    Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
      .collect(Collectors.groupingBy(User::getId));
    // 2. 填充信息
    pictureVOList.forEach(pictureVO -> {
      Long userId = pictureVO.getUserId();
      User user = null;
      if (userIdUserListMap.containsKey(userId)) {
        user = userIdUserListMap.get(userId).get(0);
      }
      pictureVO.setUser(userService.getUserVo(user));
    });
    pictureVOPage.setRecords(pictureVOList);
    return pictureVOPage;
  }

  @Override
  public void validPicture(Picture picture) {
    ThrowUtils.throwIf(picture == null, ErrorCode.PARAMS_ERROR);
    // 从对象中取值
    Long id = picture.getId();
    String url = picture.getUrl();
    String introduction = picture.getIntroduction();
    // 修改数据时，id 不能为空，有参数则校验
    ThrowUtils.throwIf(ObjUtil.isNull(id), ErrorCode.PARAMS_ERROR, "id 不能为空");
    if (StrUtil.isNotBlank(url)) {
      ThrowUtils.throwIf(url.length() > 1024, ErrorCode.PARAMS_ERROR, "url 过长");
    }
    if (StrUtil.isNotBlank(introduction)) {
      ThrowUtils.throwIf(introduction.length() > 800, ErrorCode.PARAMS_ERROR, "简介过长");
    }
  }

  /**
   * 图片审核
   *
   * @param pictureReviewRequest
   * @param loginUser
   */
  @Override
  public void doPictureReview(PictureReviewRequest pictureReviewRequest, User loginUser) {
    Long id = pictureReviewRequest.getId();
    Integer reviewStatus = pictureReviewRequest.getReviewStatus();
    PictureReviewStatusEnum reviewStatusEnum = PictureReviewStatusEnum.getEnumByValue(reviewStatus);
    if (id == null || reviewStatusEnum == null || PictureReviewStatusEnum.REVIEWING.equals(reviewStatusEnum)) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }

    //判断是否存在
    Picture oldPicture = this.getById(id);
    if (oldPicture == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
    }
    //已是该状态
    if (oldPicture.getReviewStatus().equals(reviewStatus)) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "请勿重复审核");
    }
    //更新图片状态
    Picture picture = new Picture();
    BeanUtils.copyProperties(pictureReviewRequest, picture);
    picture.setReviewerId(loginUser.getId());
    picture.setReviewTime(new Date());
    boolean result = this.updateById(picture);
    ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "操作失败");
  }

  /**
   * 填充入库图片信息
   *
   * @param picture
   * @param loginUser
   */
  @Override
  public void fillReviewParams(Picture picture, User loginUser) {
    if (userService.isAdmin(loginUser)) {
      picture.setReviewMessage("管理员自动通过");
      picture.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());
      picture.setReviewerId(picture.getId());
      picture.setReviewTime(new Date());
    } else {
      //非管理员则为待审核
      picture.setReviewStatus(PictureReviewStatusEnum.REVIEWING.getValue());
    }
  }

  /**
   * 批量抓取图片
   *
   * @param pictureUploadByBatchRequest
   * @param loginUser
   * @return 抓取图片数量
   */
  @Override
  public int uploadPictureByBatch(PictureUploadByBatchRequest pictureUploadByBatchRequest, User loginUser) {
    String searchText = pictureUploadByBatchRequest.getSearchText();
    //格式化数量
    Integer count = pictureUploadByBatchRequest.getCount();
    ThrowUtils.throwIf(pictureUploadByBatchRequest.getCount() > 30, ErrorCode.PARAMS_ERROR, "最多抓取30条");
    String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1", searchText);
    String namePrefix = pictureUploadByBatchRequest.getNamePrefix();
    if (StrUtil.isBlank(namePrefix)) {
      namePrefix = searchText;
    }
    Document document = null;
    try {
      document = Jsoup.connect(fetchUrl).get();
    } catch (IOException e) {
      log.error("获取页面失败", e);
      throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取页面失败");
    }
    Element div = document.getElementsByClass("dgControl").first();
    if (ObjectUtil.isNull(div)) {
      throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取元素失败");
    }
    Elements imgElementList = div.select("img.mimg");
    int uploadCount = 0;
    for (Element element : imgElementList) {
      String fileUrl = element.attr("src");
      if (StrUtil.isBlank(fileUrl)) {
        log.info("当前链接为空，已跳过:{}",fileUrl);
        continue;
      }
      //处理地址，防止转义
      int questionMarkIndex = fileUrl.indexOf("?");
      if (questionMarkIndex > -1) {
        fileUrl = fileUrl.substring(0, questionMarkIndex);
      }

      //上传图片
      PictureUploadRequest pictureUploadRequest = new PictureUploadRequest();
      if (StrUtil.isNotBlank(namePrefix)) {
        pictureUploadRequest.setPickName(String.valueOf((Integer.parseInt(namePrefix)+ (uploadCount + 1))));
      }
      try {
        PictureVO pictureVO = this.uploadPicture(fileUrl, pictureUploadRequest, loginUser);
        log.info("图片上传成功，id：{}", pictureVO.getId());
        uploadCount++;
      } catch (RuntimeException e) {
        log.error("图片上传失败", e);
        continue;
      }
      if (uploadCount >= count) {
        break;
      }
    }

    return uploadCount;
  }

  @Override
  public void checkPictureAuth(User loginUser, Picture picture) {
    Long spaceId = picture.getSpaceId();
    if (spaceId == null) {
      if (!picture.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
        throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "仅本人或管理可操作");
      }
    } else {
      if (!picture.getUserId().equals(loginUser.getId())) {
        throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "私有图片仅本人可操作");
      }
    }

  }

  @Override
  public boolean deletePicture(Long pictureId, User loginUser) {
    // 判断是否存在
    Picture oldPicture = this.getById(pictureId);
    ThrowUtils.throwIf(oldPicture == null, ErrorCode.PARAMS_ERROR);
//    checkPictureAuth(loginUser, oldPicture);
    // 操作数据库
    transactionTemplate.execute(status -> {
      boolean result = this.removeById(pictureId);
      ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "删除失败");
      Long spaceId = oldPicture.getSpaceId();
      if (spaceId != null) {
        boolean update = spaceService.lambdaUpdate().eq(Space::getId, spaceId)
          .setSql("totalSize = totalSize - ", oldPicture.getPicSize())
          .setSql("totalCount = totalCount - 1")
          .update();
        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "释放额度失败");
      }
      return true;
    });
    this.clearPictureFile(oldPicture);
    return true;
  }

  @Override
  @Async
  public void clearPictureFile(Picture oldPicture) {
    String pictureUrl = oldPicture.getUrl();
    Long count = this.lambdaQuery().eq(Picture::getUrl, pictureUrl)
      .count();

    if (count > 1) {
      return;
    }
    cosManager.deletePictureObject(oldPicture.getUrl());

    String thumbnailUrl = oldPicture.getThumbnailUrl();
    if (StrUtil.isNotBlank(thumbnailUrl)) {
      cosManager.deletePictureObject(thumbnailUrl);
    }
  }

  @Override
  public void editPicture(PictureEditRequest pictureEditRequest, User loginUser) {
    // 在此处将实体类和 DTO 进行转换
    Picture picture = new Picture();
    BeanUtils.copyProperties(pictureEditRequest, picture);
    // 注意将 list 转为 string
    picture.setTags(JSONUtil.toJsonStr(pictureEditRequest.getTags()));
    // 设置编辑时间
    picture.setEditTime(new Date());
    // 数据校验
    this.validPicture(picture);
    // 判断是否存在
    Long pictureId = pictureEditRequest.getId();
    if (pictureId != null) {
      Picture oldPicture = this.getById(pictureId);
      ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR);
//      checkPictureAuth(loginUser, oldPicture);
    }
    this.fillReviewParams(picture, loginUser);
    // 操作数据库
    boolean result = this.updateById(picture);
    ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
  }

  /**
   * 颜色搜索
   *
   * @param spaceId
   * @param picColor
   * @param loginUser
   * @return
   */
  @Override
  public List<PictureVO> searchPictureByColor(Long spaceId, String picColor, User loginUser) {
    ThrowUtils.throwIf(spaceId == null || StrUtil.isBlank(picColor), ErrorCode.PARAMS_ERROR);
    ThrowUtils.throwIf(loginUser == null, ErrorCode.PARAMS_ERROR);
    Space space = spaceService.getById(spaceId);
    if (space == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "空间不存在");
    }
    if (!loginUser.getId().equals(space.getUserId())) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有空间访问权限");
    }
    List<Picture> pictureList = this.lambdaQuery()
      .eq(Picture::getSpaceId, space)
      .isNotNull(Picture::getPicColor)
      .list();
    Color targetColor = Color.decode(picColor);
    List<Picture> sortedPictures = pictureList.stream()
      .sorted(Comparator.comparingDouble(picture -> {
        String hexColor = picture.getPicColor();
        if (StrUtil.isBlank(hexColor)) {
          return Double.MAX_VALUE;
        }
        Color pictureColor = Color.decode(hexColor);
        return -ColorSimilarUtils.calculateSimilarity(targetColor, pictureColor);
      }))
      .limit(12)
      .collect(Collectors.toList());

    return sortedPictures.stream().map(PictureVO::objToVo).collect(Collectors.toList());
  }

  /**
   * 批量修改图片
   *
   * @param pictureEditByBatchRequest
   * @param loginUser
   */
  @Override
  public void editPictureByBatch(PictureEditByBatchRequest pictureEditByBatchRequest, User loginUser) {
    List<Long> pictureIdList = pictureEditByBatchRequest.getPictureIdList();
    Long spaceId = pictureEditByBatchRequest.getSpaceId();
    String category = pictureEditByBatchRequest.getCategory();
    List<String> tags = pictureEditByBatchRequest.getTags();
    String nameRule = pictureEditByBatchRequest.getNameRule();
    //校验参数以及权限
    validateBatchEditRequest(spaceId, pictureIdList, loginUser);

    List<Picture> pictureList = this.lambdaQuery()
      .select(Picture::getId, Picture::getSpaceId)
      .in(Picture::getId, pictureIdList)
      .eq(Picture::getSpaceId, spaceId)
      .list();

    fillPictureWithNameRule(pictureList, nameRule);

    if (pictureList.isEmpty()) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "指定的图片不存在或者不属于该空间");
    }

    //线程吃 + 异步编程优化
    int batchSize = 100;
    List<CompletableFuture<Void>> futures = new ArrayList<>();

    for (int i = 0; i < pictureList.size(); i += batchSize) {
      List<Picture> pictures = pictureList.subList(i, Math.min(i + batchSize, pictureList.size()));

      CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        pictures.forEach(picture -> {
          if (StrUtil.isNotBlank(category)) {
            picture.setCategory(category);
          }

          if (CollUtil.isNotEmpty(tags)) {
            picture.setTags(JSONUtil.toJsonStr(tags));
          }

        });
        boolean result = this.updateBatchById(pictures);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "批量更新图片失败");
      }, threadPoolExecutor);
      futures.add(future);
    }

    //等待所有任务完成
    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
  }

  @Override
  public CreateOutPaintingTaskResponse createOutPaintingTask(CreatePictureOutPaintingTaskRequest createPictureOutPaintingTaskRequest, User loginUser) {
    Long pictureId = createPictureOutPaintingTaskRequest.getPictureId();
    Picture picture = Optional.ofNullable(this.getById(pictureId))
      .orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND_ERROR, "图片不存在"));

    //校验权限
//    checkPictureAuth(loginUser, picture);

    //构造信息参数
    CreateOutPaintingTaskRequest createOutPaintingTaskRequest = new CreateOutPaintingTaskRequest();
    CreateOutPaintingTaskRequest.Input input = new CreateOutPaintingTaskRequest().getInput();
    input.setImageUrl(picture.getUrl());
    createOutPaintingTaskRequest.setInput(input);
    BeanUtils.copyProperties(createPictureOutPaintingTaskRequest, createOutPaintingTaskRequest);

    //创建任务
    return aliYunAiApi.createOutPaintingTask(createOutPaintingTaskRequest);

  }

  /**
   * 根据规则填充图片名称
   * @param pictureList
   * @param nameRule
   */
  private void fillPictureWithNameRule(List<Picture> pictureList, String nameRule) {
    if (CollUtil.isEmpty(pictureList) || StrUtil.isBlank(nameRule)) {
      return;
    }
    int count = 1;
    try {
      for (Picture picture : pictureList) {
        picture.setName(nameRule.replaceAll("\\{序号}", String.valueOf(count)));
        count++;
      }
    } catch (Exception e) {
      log.error("名称解析异常", e);
      throw new BusinessException(ErrorCode.OPERATION_ERROR, "名称解析异常");
    }

  }

  /**
   * 批量修改校验参数以及权限
   *
   * @param spaceId
   * @param pictureIdList
   * @param loginUser
   */
  private void validateBatchEditRequest(Long spaceId, List<Long> pictureIdList, User loginUser) {
    ThrowUtils.throwIf(spaceId == null || CollectionUtil.isEmpty(pictureIdList), ErrorCode.PARAMS_ERROR);
    ThrowUtils.throwIf(loginUser == null, ErrorCode.PARAMS_ERROR);

    //校验空间权限
    Space space = spaceService.getById(spaceId);
    ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
    if (!space.getUserId().equals(loginUser.getId())) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无空间权限");
    }

  }
}




